package com.nov.multidatasource.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSONObject;
import com.nov.multidatasource.config.RunBatchConfig;
import com.nov.multidatasource.dao.primary.V3FileInfoMapper;
import com.nov.multidatasource.dao.secondary.V6FileInfoMapper;
import com.nov.multidatasource.entity.primary.TCenterFileBaseIndex;
import com.nov.multidatasource.entity.secondary.PanGangTFileBaseIndex;
import com.nov.multidatasource.service.CMFileInfoService;
import com.nov.multidatasource.service.RunBatchService;
import com.tecrun.common.constant.ResultCode;
import com.tecrun.common.utils.DateUtils;
import com.tecrun.common.vo.RtnData;
import io.minio.*;
import io.minio.errors.*;
import io.minio.http.Method;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.MapUtils;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.io.IOException;
import java.io.InputStream;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;


/**
 * @ClassName RunBatchService
 * @Description TODO
 * @Author cxn
 * @CreateTime 2024/12/24 14:44
 * @Since 1.0.0
 */
@Slf4j
@Service
public class RunBatchServiceImpl implements RunBatchService {

    @Resource
    private RunBatchConfig runBatchConfig;

    @Resource
    private CMFileInfoService cmFileInfoService;
    @Resource
    private V3FileInfoMapper v3FileInfoMapper;
    @Resource
    private V6FileInfoMapper v6FileInfoMapper;


    /**
     * 鞍钢minio
     */
    public static String endpoint = "https://oss.ansteel.cn:443";
    public static String accessKey = "CNHv5HCwe0e12kzjoB8Y";
    public static String secretKey = "fsimagebucket1DkMyzf0sWabnpOyP9iTyb";
    public static String bucket = "fs-image-bucket-prd";

    /**
     * 攀钢minio
     */
    public static String pan_endpoint = "http://10.128.35.242:9000";
    public static String pan_accessKey = "EtX2ppTKSgUBy9BRcb9k";
    public static String pan_secretKey = "rGV2mtncc5jWPgsvB7tTNDN9dpZZzk6o1omGU38N";
    public static String pan_bucket = "pg-image";

    /**
     * 写入本地路径
     */
    public static String local_path = "/home/tecrun/runbatch/";

    @Override
    @Scheduled(cron = "0 0 0 * * ?")
    public RtnData markSyncDone() {

        // 开始时间
        long start = System.currentTimeMillis();
        // 可执行时间
        //long executeTime = System.currentTimeMillis() + 1 * 1000 * 60 * 60;
        long executeTime = System.currentTimeMillis() + 3 * 1000 * 60 * 60;
        log.info("markSyncDone 定时任务触发时间: start{}, time:{}", start, DateUtil.format(new Date(start), "yyyy-MM-dd HH:mm:ss"));
        if (start < executeTime) {
            // 查询总个数
            int totalCount = v6FileInfoMapper.queryPanGangDataCount();
            if (totalCount <= 0) {
                log.warn("执行的总数量查询是空, startTime:{}, 结束耗时:{}", start, (System.currentTimeMillis() - start));
                return RtnData.success(ResultCode.ERROR.getCode(), ResultCode.ERROR.getMsg(), "FAIL");
            }
            log.info("此次执行总文件数量:{}", totalCount);
            try {
                int threadHandlerDataLimit = Integer.parseInt(runBatchConfig.getThreadHandlerDataLimit());
                int pageCount = getPageCount(totalCount, threadHandlerDataLimit);
                log.info("当前任务执行执行:{}次", pageCount);
                for (int k = 0; k < pageCount; k++) {
                    log.info("当前任务执行执行:第{}次", k + 1);
                    List<Map<String, Object>> panGangDataLimit = v6FileInfoMapper.queryPanGangData(0, threadHandlerDataLimit);
                    if (CollUtil.isEmpty(panGangDataLimit)) {
                        log.warn("数据查出来是空");
                        break;
                    }
                    List<String> fileIds = panGangDataLimit.stream().filter(m -> StrUtil.isNotBlank(MapUtils.getString(m, "FILE_ID"))).map(m -> MapUtils.getString(m, "FILE_ID")).collect(Collectors.toList());
                    List<PanGangTFileBaseIndex> panGangTFileBaseIndices = v6FileInfoMapper.queryFileByFileIds(fileIds);
                    log.info("panGangTFileBaseIndices count:{}", panGangTFileBaseIndices.size());
                    start = System.currentTimeMillis();
                    if (start < executeTime) {
                        List<TCenterFileBaseIndex> addList = new ArrayList<>();
                        List<String> editList = new ArrayList<>();
                        for (PanGangTFileBaseIndex panGangData : panGangTFileBaseIndices) {
                            // 1. 遍历每个文件在共享中心存在不存在
                            String fileId = panGangData.getFILE_ID();
                            List<String> shareBaseIndexByFileId = v3FileInfoMapper.getShareBaseIndexByFileId(fileId);
                            if (CollUtil.isEmpty(shareBaseIndexByFileId)) {
                                log.warn("文件id:{}, 在共享池里面索引不存在！！！", fileId);
                                log.info("共享中心文件id:{}, 不存在", fileId);
                                // 推送共享中心
                                TCenterFileBaseIndex tCenterFileBaseIndex = new TCenterFileBaseIndex();
                                tCenterFileBaseIndex.setID(IdUtil.getSnowflake(1, 10).nextId());
                                tCenterFileBaseIndex.setFILE_ID(panGangData.getFILE_ID());
                                tCenterFileBaseIndex.setFILE_NAME(panGangData.getFILE_NAME());
                                tCenterFileBaseIndex.setFILE_TYPE(panGangData.getFILE_TYPE());
                                tCenterFileBaseIndex.setFILE_SUFFIX(panGangData.getFILE_SUFFIX());
                                tCenterFileBaseIndex.setFILE_SIZE(StrUtil.isBlank(panGangData.getFILE_SIZE())? "0" : panGangData.getFILE_SIZE());
                                tCenterFileBaseIndex.setFILE_PATH(panGangData.getFILE_IMAGE_OBJECT0());
                                tCenterFileBaseIndex.setPART_CENTER_NAME("攀钢");
                                tCenterFileBaseIndex.setPART_CENTER_CODE("pangang");
                                tCenterFileBaseIndex.setBUSI_SERIAL_NO(panGangData.getBUSI_SERIAL_NO());
                                tCenterFileBaseIndex.setBILL_NUM(StrUtil.isBlank(panGangData.getBILL_NUM()) ? "0" : panGangData.getBILL_NUM());
                                tCenterFileBaseIndex.setBUSI_TYPE_CODE(panGangData.getBUSI_CODE());
                                tCenterFileBaseIndex.setBUSI_TYPE_NAME(panGangData.getBUSI_TYPE_NAME());
                                tCenterFileBaseIndex.setBILL_ORG_CODE(panGangData.getORG_CODE());
                                tCenterFileBaseIndex.setBILL_ORG_NAME("");
                                tCenterFileBaseIndex.setUPLOAD_BATCH_ID(panGangData.getUPLOAD_BATCH_ID());
                                tCenterFileBaseIndex.setFILE_SYNC_TIME(String.valueOf(DateUtils.dateTimeNow()));
                                tCenterFileBaseIndex.setINDEX_VERSION(1);
                                tCenterFileBaseIndex.setCREATE_BY(panGangData.getCREATE_USER());
                                tCenterFileBaseIndex.setBUSI_SYSTEM_CODE("PANGANG");
                                tCenterFileBaseIndex.setBUSI_SYSTEM_NAME("攀钢");
                                SimpleDateFormat outputFormat = new SimpleDateFormat("yyyyMMddHHmmss");
                                if (StrUtil.isNotBlank(panGangData.getCREATE_TIME())) {
                                    // 格式化日期为目标格式
                                    cn.hutool.core.date.DateTime dateTime = DateUtil.parse(panGangData.getCREATE_TIME(), "yyyy-MM-dd HH:mm:ss");
                                    String outputDate = DateUtil.format(dateTime, "yyyyMMddHHmmss");
                                    tCenterFileBaseIndex.setCREATE_TIME(outputDate);
                                } else {
                                    tCenterFileBaseIndex.setCREATE_TIME("");
                                }
                                tCenterFileBaseIndex.setDELETED(0);
                                tCenterFileBaseIndex.setFILE_SYNC_STATE(2);// 代表索引同步
                                tCenterFileBaseIndex.setCREATE_USER_NO(panGangData.getCREATE_USER_NO());
                                tCenterFileBaseIndex.setCOMMENT_USER_NAME("mzq");
                                addList.add(tCenterFileBaseIndex);
                                log.info("fileId:{}, 共享中心同步", fileId);
                            } else {
                                //更新共享中心状态 已同步 2
                                log.info("fileId:{}, 更新索引状态", fileId);
                                editList.add(fileId);
                            }
                        }
                        // 批量新增共享中心数据
                        if(addList.size() > 0){
                            for (int i = 0; i < addList.size(); i += 100) {
                                int endIndex = Math.min(i + 100, addList.size());
                                List<TCenterFileBaseIndex> sub = CollUtil.sub(addList, i, endIndex);
                                try {
                                    int insert = v3FileInfoMapper.batchInsertTCenterFileBaseIndex(sub);
                                    log.info("批量插入成功的条数:{}, 当前执行批次:{}", insert, k + 1);
                                } catch (Exception e) {
                                    e.printStackTrace();
                                    // 插入失败的fileId写入本地
                                    List<String> colFileIds = sub.stream().map(TCenterFileBaseIndex::getFILE_ID).collect(Collectors.toList());
                                    FileUtil.appendLines(colFileIds, local_path + (k + 1)  + "_" + i +  ".txt", "utf-8");
                                }

                                //更新攀钢数据库已同步
                                List<String> fileId = sub.stream().filter(m -> StrUtil.isNotBlank(m.getFILE_ID())).map(TCenterFileBaseIndex::getFILE_ID).collect(Collectors.toList());
                                v6FileInfoMapper.batchUpdateFileSyncStatus(fileId, 2);
                            }

                        }
                        // 批量更新文件同步状态
                        if(editList.size() > 0){
                            //更新共享中心状态 已同步 2
                            v3FileInfoMapper.batchUpdateFileSyncStatus(editList, 2);
                            //更新攀钢数据库已同步
                            v6FileInfoMapper.batchUpdateFileSyncStatus(editList, 2);
                        }

                    } else {
                        // 结束当前线程
                        throw new RuntimeException("当前线程结束");
                    }
                }


            } catch (Exception e) {
                e.printStackTrace();
                log.info("任务执行失败", e);
                return RtnData.success("FAIL");
            }

        }
        return RtnData.success("SUCCESS");
    }

    public int getPageCount(int totalCount, int pageSize) {
        return totalCount % pageSize == 0 ? totalCount / pageSize : (totalCount / pageSize + 1);
    }

    /**
     * 针对失败的文件重新跑
     */
    public RtnData runFailTxtFile(String path){
        // 1. 读取文件txt的失败文件id
        List<String> fileIds = new ArrayList<>();
        if(StrUtil.isNotBlank(path)){
            fileIds = FileUtil.readUtf8Lines(path);
        }else{
            fileIds = FileUtil.readUtf8Lines("C:\\Users\\123\\Desktop\\生产包\\107nginx\\17.txt");
        }
        List<String> notBlankFileIds = fileIds.stream().filter(StrUtil::isNotBlank).collect(Collectors.toList());
        List<PanGangTFileBaseIndex> panGangTFileBaseIndices = v6FileInfoMapper.queryFileByFileIds(notBlankFileIds);
        List<String> failList = new ArrayList<>();
        for (PanGangTFileBaseIndex panGangData : panGangTFileBaseIndices) {
            // 1. 遍历每个文件在共享中心存在不存在
            String fileId = panGangData.getFILE_ID();
            List<String> shareBaseIndexByFileId = v3FileInfoMapper.getShareBaseIndexByFileId(fileId);
            if (CollUtil.isEmpty(shareBaseIndexByFileId)) {
                log.info("共享中心文件id:{}, 不存在", fileId);
                // 推送共享中心
                TCenterFileBaseIndex tCenterFileBaseIndex = new TCenterFileBaseIndex();
                tCenterFileBaseIndex.setID(IdUtil.getSnowflake(1, 10).nextId());
                tCenterFileBaseIndex.setFILE_ID(panGangData.getFILE_ID());
                tCenterFileBaseIndex.setFILE_NAME(panGangData.getFILE_NAME());
                tCenterFileBaseIndex.setFILE_TYPE(panGangData.getFILE_TYPE());
                tCenterFileBaseIndex.setFILE_SUFFIX(panGangData.getFILE_SUFFIX());
                tCenterFileBaseIndex.setFILE_SIZE(StrUtil.isBlank(panGangData.getFILE_SIZE())? "0" : panGangData.getFILE_SIZE());
                tCenterFileBaseIndex.setFILE_PATH(panGangData.getFILE_IMAGE_OBJECT0());
                tCenterFileBaseIndex.setPART_CENTER_NAME("攀钢");
                tCenterFileBaseIndex.setPART_CENTER_CODE("pangang");
                tCenterFileBaseIndex.setBUSI_SERIAL_NO(panGangData.getBUSI_SERIAL_NO());
                tCenterFileBaseIndex.setBILL_NUM(StrUtil.isBlank(panGangData.getBILL_NUM()) ? "0" : panGangData.getBILL_NUM());
                tCenterFileBaseIndex.setBUSI_TYPE_CODE(panGangData.getBUSI_CODE());
                tCenterFileBaseIndex.setBUSI_TYPE_NAME(panGangData.getBUSI_TYPE_NAME());
                tCenterFileBaseIndex.setBILL_ORG_CODE(panGangData.getORG_CODE());
                tCenterFileBaseIndex.setBILL_ORG_NAME("");
                tCenterFileBaseIndex.setUPLOAD_BATCH_ID(panGangData.getUPLOAD_BATCH_ID());
                tCenterFileBaseIndex.setFILE_SYNC_TIME(String.valueOf(DateUtils.dateTimeNow()));
                tCenterFileBaseIndex.setINDEX_VERSION(1);
                tCenterFileBaseIndex.setCREATE_BY(panGangData.getCREATE_USER());
                tCenterFileBaseIndex.setBUSI_SYSTEM_CODE("PANGANG");
                tCenterFileBaseIndex.setBUSI_SYSTEM_NAME("攀钢");
                if (StrUtil.isNotBlank(panGangData.getCREATE_TIME())) {
                    // 格式化日期为目标格式
                    cn.hutool.core.date.DateTime dateTime = DateUtil.parse(panGangData.getCREATE_TIME(), "yyyy-MM-dd HH:mm:ss");
                    String outputDate = DateUtil.format(dateTime, "yyyyMMddHHmmss");
                    tCenterFileBaseIndex.setCREATE_TIME(outputDate);
                } else {
                    tCenterFileBaseIndex.setCREATE_TIME("");
                }
                tCenterFileBaseIndex.setDELETED(0);
                tCenterFileBaseIndex.setFILE_SYNC_STATE(2);// 代表索引同步
                tCenterFileBaseIndex.setCREATE_USER_NO(panGangData.getCREATE_USER_NO());
                tCenterFileBaseIndex.setCOMMENT_USER_NAME("mzq");
                log.info("fileId:{}, 插入共享中心同步", fileId);
                try {
                    v3FileInfoMapper.batchInsertTCenterFileBaseIndex(CollUtil.newArrayList(tCenterFileBaseIndex));
                } catch (Exception e) {
                    e.printStackTrace();
                    failList.add(fileId);
                }
                v6FileInfoMapper.batchUpdateFileSyncStatus(CollUtil.newArrayList(fileId), 2);
            } else {
                //更新共享中心状态 已同步 2
                log.info("fileId:{}, 更新索引状态", fileId);
                //更新共享中心状态 已同步 2
                v3FileInfoMapper.batchUpdateFileSyncStatus(CollUtil.newArrayList(fileId), 2);
                //更新攀钢数据库已同步
                v6FileInfoMapper.batchUpdateFileSyncStatus(CollUtil.newArrayList(fileId), 2);
            }
        }

        return RtnData.success(failList);
    }

    /**
     * minio 同步
     */
    @Scheduled(cron = "0 0 22 * * ?")
    public RtnData syncPanGangMinio(){

        // 开始时间
        long start = System.currentTimeMillis();
        log.info("syncPanGangMinio statTime:{}", start);

        // 创建攀钢minioClient
        MinioClient panGangClient = MinioClient.builder()
                .endpoint(pan_endpoint)
                .credentials(pan_accessKey, pan_secretKey)
                .build();

        // 创建鞍钢minioClient
        MinioClient anGangClient = MinioClient.builder()
                .endpoint(endpoint)
                .credentials(accessKey, secretKey)
                .build();

        // 可执行时间
        long executeTime = start + 2 * 1000 * 60 * 60;
        log.info("syncPanGangMinio 定时任务触发时间: time:{}",  DateUtil.format(new Date(start), "yyyy-MM-dd HH:mm:ss"));
        if (start < executeTime) {
            // 查询共享中心有那些攀钢的文件
            int totalCount = v3FileInfoMapper.queryPangangCenterFileIndexCount();
            if (totalCount <= 0) {
                log.warn("执行的总数量查询是空, startTime:{}, 结束耗时:{}", start, (System.currentTimeMillis() - start));
                return RtnData.success(ResultCode.ERROR.getCode(), ResultCode.ERROR.getMsg(), "FAIL");
            }

            log.info("此次执行总文件数量:{}", totalCount);
            try {
                int threadHandlerDataLimit = Integer.parseInt(runBatchConfig.getThreadHandlerDataLimit());
                int pageCount = getPageCount(totalCount, threadHandlerDataLimit);
                log.info("当前任务执行执行:{}次", pageCount);

                for (int k = 0; k < pageCount; k++) {
                    log.info("当前任务执行执行:第{}次", k + 1);
                    List<TCenterFileBaseIndex> panGangDataLimit = v3FileInfoMapper.queryPangangCenterFileIndex(k * threadHandlerDataLimit,  threadHandlerDataLimit);
                    if (CollUtil.isEmpty(panGangDataLimit)) {
                        log.warn("数据查出来是空");
                        break;
                    }

                    // 每个批次判断是否执行小于指定的执行时间
                    if (System.currentTimeMillis() < executeTime) {
                        List<String> success = new ArrayList<>();
                        List<String> fail = new ArrayList<>();
                        for (TCenterFileBaseIndex panGangData : panGangDataLimit) {
                            // 1. 判断filePath是否为空
                            String fileID = panGangData.getFILE_ID();
                            try {
                                if(StrUtil.isNotBlank(panGangData.getFILE_PATH())){
                                    // 连接攀钢的minio转成流存储到鞍钢的minio里面
                                    try{
                                        //判断在鞍钢的minio是否存在
                                        if (!fileExists(anGangClient, bucket, panGangData.getFILE_PATH())) {
                                            StatObjectResponse stat = panGangClient.statObject(StatObjectArgs.builder()
                                                    .bucket(pan_bucket)
                                                    .object(panGangData.getFILE_PATH())
                                                    .build());
                                            long fileSize = stat.size();
                                            if(fileSize <= 0){
                                                log.info("文件id:{}, 在攀钢的存储不存在", panGangData.getFILE_ID());
                                                fail.add(panGangData.getFILE_ID());
                                                continue;
                                            }

                                            String contentType = stat.contentType() != null ? stat.contentType() : "application/octet-stream";
                                            // 分片大小设置为5MB（Minio要求至少5MB）
                                            int partSize = 5 * 1024 * 1024;

                                            boolean updateFlag = true;
                                            try (InputStream fileStream = panGangClient.getObject(GetObjectArgs.builder().bucket(pan_bucket).object(panGangData.getFILE_PATH()).build())) {
                                                anGangClient.putObject(PutObjectArgs.builder()
                                                        .bucket(bucket)
                                                        .object(panGangData.getFILE_PATH())
                                                        .stream(fileStream, fileSize, partSize)
                                                        .contentType(contentType)
                                                        .build());
                                            }catch(Exception e){
                                                log.error("文件id:"+panGangData.getFILE_ID()+",上传攀钢minio错误", e);
                                                updateFlag = false;
                                            }
                                            if(updateFlag){
                                                log.info("文件id:{}, filePath:{}. 攀钢迁移文件到鞍钢共享池成功", panGangData.getFILE_ID(), panGangData.getFILE_PATH());
                                                // 更新攀钢数据库同步状态是4 ,代表minio已经同步了
                                                success.add(panGangData.getFILE_ID());
                                            }else{
                                                fail.add(panGangData.getFILE_ID());
                                            }

                                        }else{
                                            //在鞍钢共享池存在
                                            success.add(panGangData.getFILE_ID());
                                        }
                                    } catch (Exception e) {
                                        log.error("fileId:"+fileID+",上传鞍钢minio处理失败", e);
                                        // 失败代表
                                        FileUtil.appendLines(CollUtil.newArrayList(panGangData.getFILE_ID()), local_path + "syncMinio.txt", "utf-8");
                                    }
                                }
                            } catch (Exception e) {
                                log.error("文件id:"+fileID+",上传攀钢minio错误", e);
                            }
                        }

                        if(success.size() > 0){
                            // 更新攀钢数据库同步状态是4 ,代表minio已经同步成功
                              v6FileInfoMapper.batchUpdateFileSyncStatus(success, 4);
                              // 更新鞍钢共享中心服务同步状态是4 ,代表minio已经同步了
                              v3FileInfoMapper.batchUpdateFileSyncStatus(success, 4);
                        }

                        if(fail.size() > 0){
                            // 更新攀钢数据库同步状态是5 ,代表minio已经同步了，但是minio同步失败
                            v6FileInfoMapper.batchUpdateFileSyncStatus(fail, 5);
                            // 更新鞍钢共享中心服务同步状态是5 ,代表minio已经同步了
                            v3FileInfoMapper.batchUpdateFileSyncStatus(fail, 5);
                        }

                    } else {
                        // 结束当前线程, 不让后续执行
                        throw new RuntimeException("当前线程结束");
                    }
                }
            } catch (Exception e) {
                log.info("任务执行失败", e);
                return RtnData.success("FAIL");
            }
        }
        return RtnData.success("SUCCESS");
    }


    public static boolean doesObjectExist(MinioClient minioClient, String bucketName, String objectId) {
        try {
            // 检查对象是否存在
            minioClient.statObject(io.minio.StatObjectArgs.builder().bucket(bucketName).object(objectId).build());
            return true;
        } catch (Exception e) {
            // 如果对象不存在，会抛出 ErrorResponseException，错误码为 NoSuchKey
            if (e instanceof ErrorResponseException && ((ErrorResponseException) e).errorResponse().code().equals("NoSuchKey")) {
                return false;
            }
            // e.printStackTrace();
            return false;
        }
    }

    public boolean fileExists(MinioClient minioClient, String bucketName, String objectId) {
        try {
            TimeUnit.MILLISECONDS.sleep(500L);
            StatObjectResponse stat = minioClient.statObject(
                    StatObjectArgs.builder().bucket(bucketName).object(objectId).build()
            );
            long fileSize = stat.size();
            if(fileSize > 0){
                return true;
            }else{
                return false;
            }
        } catch (Exception e) {
            return false;
        }
    }


    /**
     * 查找某个攀钢的文件在共享中心是否存在
     */
    public String getAnGangShareMinioUrl(String fileId) throws IOException, NoSuchAlgorithmException, InvalidKeyException, InvalidResponseException, XmlParserException, InternalException, ServerException, InsufficientDataException, ErrorResponseException {
        // 创建鞍钢minioClient
        MinioClient anGangClient = MinioClient.builder()
                .endpoint(endpoint)
                .credentials(accessKey, secretKey)
                .build();

        // 查询fileId对应bucketName
        List<String> strings = v3FileInfoMapper.queryCenterPanGangMinioPath(fileId);
        if(CollUtil.isEmpty(strings)){
            log.info("fileId:{}, 的filePath不存在", fileId);
            return StrUtil.EMPTY;
        }

        // 生成预签名 URL，有效期为 600 秒（可根据需要调整）
        String presignedUrl = anGangClient.getPresignedObjectUrl(
                GetPresignedObjectUrlArgs.builder()
                        .method(Method.GET)
                        .bucket(bucket)
                        .object(CollUtil.getFirst(strings))
                        //.expiry(1200)
                        .build());



        return presignedUrl;
    }


    /**
     * 获取攀钢本地minio的地址
     */
    public String getPanGangMinioUrl(String fileId) throws IOException, NoSuchAlgorithmException, InvalidKeyException, InvalidResponseException, XmlParserException, InternalException, ServerException, InsufficientDataException, ErrorResponseException {
        // 创建鞍钢minioClient
        MinioClient panGangClient = MinioClient.builder()
                .endpoint(pan_endpoint)
                .credentials(pan_accessKey, pan_secretKey)
                .build();

        // 查询fileId对应bucketName
        List<String> strings = v3FileInfoMapper.queryCenterPanGangMinioPath(fileId);
        if(CollUtil.isEmpty(strings)){
            log.info("fileId:{}, 的filePath不存在", fileId);
            return StrUtil.EMPTY;
        }

        // 生成预签名 URL，有效期为 600 秒（可根据需要调整）
        String presignedUrl = panGangClient.getPresignedObjectUrl(
                GetPresignedObjectUrlArgs.builder()
                        .method(Method.GET)
                        .bucket(pan_bucket)
                        .object(CollUtil.getFirst(strings))
                        //.expiry(1200)
                        .build());



        return presignedUrl;
    }

    /**
     * 同步攀钢文件到测试环境107
     * 用于测试环境跑文件及minio的方法
     */
    public void syncTestPanGangFile(String fileIds){

        // 创建测试环境 攀钢minioClient
        MinioClient panGangClient = MinioClient.builder()
                .endpoint("http://10.128.35.242:9000")
                .credentials("EtX2ppTKSgUBy9BRcb9k", "rGV2mtncc5jWPgsvB7tTNDN9dpZZzk6o1omGU38N")
                .build();

        // 创建测试环境 鞍钢minioClient
        MinioClient anGangClient = MinioClient.builder()
                .endpoint("https://oss.ansteel.cn:443")
                .credentials("CNHv5HCwe0e12kzjoB8Y", "fsimagebucket1DkMyzf0sWabnpOyP9iTyb")
                .build();

        if(StrUtil.isBlank(fileIds)){
            log.info("fileIds params is null");
        }
        List<String> split = StrUtil.split(fileIds, ',');
        // 1. 查询攀钢用于同步测试的文件
        List<PanGangTFileBaseIndex> panGangTFileBaseIndices = v6FileInfoMapper.queryFileByFileIds(split);
        for (PanGangTFileBaseIndex panGangData : panGangTFileBaseIndices) {
            // 1. 遍历每个文件在共享中心存在不存在
            String fileId = panGangData.getFILE_ID();
            try{
                //判断在鞍钢的minio是否存在
                if (!fileExists(anGangClient, "fs-image-bucket1", panGangData.getFILE_PATH())) {
                    StatObjectResponse stat = panGangClient.statObject(StatObjectArgs.builder()
                            .bucket("pg-image")
                            .object(panGangData.getFILE_PATH())
                            .build());
                    long fileSize = stat.size();
                    if(fileSize <= 0){
                        log.info("文件id:{}, 在攀钢的存储不存在", panGangData.getFILE_ID());
                        continue;
                    }

                    String contentType = stat.contentType() != null ? stat.contentType() : "application/octet-stream";
                    // 分片大小设置为5MB（Minio要求至少5MB）
                    int partSize = 5 * 1024 * 1024;

                    boolean updateFlag = true;
                    try (InputStream fileStream = panGangClient.getObject(GetObjectArgs.builder().bucket("pg-image").object(panGangData.getFILE_PATH()).build())) {
                        anGangClient.putObject(PutObjectArgs.builder()
                                .bucket("fs-image-bucket1")
                                .object(panGangData.getFILE_PATH())
                                .stream(fileStream, fileSize, partSize)
                                .contentType(contentType)
                                .build());
                    }catch(Exception e){
                        log.error("文件id,上传攀钢minio错误", e);
                        updateFlag = false;
                    }
                    if(updateFlag){
                        log.info("文件id:{}, filePath:{}. 攀钢迁移文件到鞍钢共享池成功", panGangData.getFILE_ID(), panGangData.getFILE_PATH());
                        // 更新攀钢数据库同步状态是4 ,代表minio已经同步了
                        v6FileInfoMapper.batchUpdateFileSyncStatus(CollUtil.newArrayList(panGangData.getFILE_ID()), 4);
                        // 更新鞍钢共享中心服务同步状态是4 ,代表minio已经同步了
                        v3FileInfoMapper.batchUpdateFileSyncStatus(CollUtil.newArrayList(panGangData.getFILE_ID()), 4);

                    }else{
                        // 更新攀钢数据库同步状态是4 ,代表minio已经同步了
                        v6FileInfoMapper.batchUpdateFileSyncStatus(CollUtil.newArrayList(panGangData.getFILE_ID()), 5);
                        // 更新鞍钢共享中心服务同步状态是4 ,代表minio已经同步了
                        v3FileInfoMapper.batchUpdateFileSyncStatus(CollUtil.newArrayList(panGangData.getFILE_ID()), 5);
                    }

                }else{
                    //在鞍钢共享池存在
                    v6FileInfoMapper.batchUpdateFileSyncStatus(CollUtil.newArrayList(panGangData.getFILE_ID()), 4);
                    // 更新鞍钢共享中心服务同步状态是4 ,代表minio已经同步了
                    v3FileInfoMapper.batchUpdateFileSyncStatus(CollUtil.newArrayList(panGangData.getFILE_ID()), 4);
                }
            } catch (Exception e) {
                log.error("上传鞍钢minio处理失败", e);
                // 失败代表
                FileUtil.appendLines(CollUtil.newArrayList(panGangData.getFILE_ID()), local_path + "syncMinio.txt", "utf-8");
            }
        }


    }

    /**
     *  修复filePath的问题
     */
    public void fixFilePathIndex(){
        // 1. 查询共享中心的的文件, 未同步成功的
        int count = 200;
        int limit = 10000;
        for (int k = 0; k < count; k++) {
            log.info("fixFilePathIndex 处理第"+k + 1+"次");
            List<TCenterFileBaseIndex> tCenterFileBaseIndices = v3FileInfoMapper.queryPangangCenterFileIndex(k * limit, limit);
            if(CollUtil.isEmpty(tCenterFileBaseIndices)){
                log.info("tCenterFileBaseIndices size is null");
                return ;
            }
            for (TCenterFileBaseIndex tCenterFileBaseIndex : tCenterFileBaseIndices) {
                //取出来filePath和攀钢的file_image_object0做比较
                String file_path = tCenterFileBaseIndex.getFILE_PATH();
                //取攀钢的文file_image_object0
                List<String> strings = v6FileInfoMapper.queryFileImageObject0ByFileId(tCenterFileBaseIndex.getFILE_ID());
                if(CollUtil.isEmpty(strings)){
                    log.info("fixFilePathIndex fileId:{}, file_path在攀钢文件表ext里面不存在", tCenterFileBaseIndex.getFILE_ID());
                    continue;
                }
                if(!StrUtil.equals(CollUtil.getFirst(strings), file_path)){
                    log.info("fixFilePathIndex fileId:{}, filePath 两边数据不一致", tCenterFileBaseIndex.getFILE_ID());
                    //在鞍钢的共享池里面，更新filePath
                    v3FileInfoMapper.updateFilePathByFileId(tCenterFileBaseIndex.getFILE_ID(), CollUtil.getFirst(strings));
                }
            }

        }

    }

    //@Scheduled(cron = "0 0/1 * * * ?")
    public void testScheduled()  {

        try {
            // 开始时间
            long start = System.currentTimeMillis();
            log.info("syncPanGangMinio statTime:{}", start);

            TimeUnit.MILLISECONDS.sleep(30 * 1000);

            // 结束当前线程
            throw new RuntimeException("当前线程结束");
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
    }


}
